package edu.ntu.cloudroid.model.policy;

import java.io.Serializable;
import java.util.Arrays;

import javax.jdo.annotations.Discriminator;
import javax.jdo.annotations.DiscriminatorStrategy;
import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.IdentityType;
import javax.jdo.annotations.Inheritance;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;

import com.google.appengine.api.datastore.Key;

import edu.ntu.cloudroid.model.GAEData;
import edu.ntu.cloudroid.xacml.builder.policy.AbstractPolicyBuilder;
import edu.ntu.cloudroid.xacml.obligation.ObligationHandle;

@PersistenceCapable(identityType = IdentityType.APPLICATION, detachable = "true")
@Inheritance
@Discriminator(strategy=DiscriminatorStrategy.CLASS_NAME)
public abstract class AbstractPrivacyPreference implements Serializable, GAEData {	
	
	public static final int DEFAULT_GRANULARITY = 1;
	public static final double DEFAULT_DISTANCE_RADIUS = 30.0;
	public static final int DEFAULT_LOWER_TIME_HOUR = 0;
	public static final int DEFAULT_LOWER_TIME_MINUTE = 0;
	public static final int DEFAULT_UPPER_TIME_HOUR = 23;
	public static final int DEFAULT_UPPER_TIME_MINUTE = 59;

	public static final int ISGROUP = 1;
	public static final int ISUSER = 2;
	public static final int ISALL = 0;
	
	/* begin filtering */
	public static final int GEQUAL = 0;
	public static final int EQUAL = 1;
	public static final int LEQUAL = 2;
	public static final int TIMECOMP = 3;

	public static final int TIMECONSTRAINT = 0;
	public static final int VALUECONSTRAINT = 1;
	
	private static final long serialVersionUID = 1L;
	@PrimaryKey
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
    private Key key;
	
	@Persistent 
	private String userName;
	
	public void setUserName(String un){
		this.userName = un;
	}
	
	public String getUserName(){
		return this.userName;
	}
	
	@Persistent
	protected boolean latestDataOnly = false;
	
	@Persistent
	protected boolean isGroupPolicy = false;
	
	@Persistent 
	int accessType; 
	@Persistent 
	String accessSubject;
	
	@Persistent
	private int dataColumnIndex;
	
	public int getDataColumnIndex() {
		return dataColumnIndex;
	}

	public void setDataColumnIndex(int dataColumnIndex) {
		this.dataColumnIndex = dataColumnIndex;
	}
	
	public boolean isGroupPolicy(){
		return this.isGroupPolicy;
	}
	
	public int getAccessType() {
		return accessType;
	}

	public void setAccessType(int accessType) {
		this.accessType = accessType;
	}

	public String getAccessSubject() {
		return accessSubject;
	}

	public void setAccessSubject(String accessSubject) {
		this.accessSubject = accessSubject;
	}

	public void setLatestDataOnly(boolean latestDataOnly) {
		this.latestDataOnly = latestDataOnly;
	}

	//@Persistent(mappedBy = "defaultPrivacyPreference") 
	public Key getKey() {
		return key;
	}
	
	public boolean isLatestDataOnly(){
		return this.latestDataOnly;
	}
	
	public void initialize(String[] values) throws Exception{
		int startingIdx = 2;
		int i = startingIdx; //skipping the user ID
		if (values[i].equals("all"))
			this.accessType = ISALL;
		else if (values[i].equals("user"))
			this.accessType = ISUSER;
		else if (values[i].equals("group"))
			this.accessType = ISGROUP;

		i++;
		if (this.accessType == ISUSER){
			this.accessSubject = values[i];
			this.isGroupPolicy = true;
			i++; 
		}
		else if (this.accessType == ISGROUP){
			this.accessSubject = values[i];
			this.isGroupPolicy = true;
			i++;
		}
		int m= values.length-i;
		String[] subVals = new String[m];
		for (int j=0; j<m; j++){
			subVals[j] = values[i+j];
		}
		initializePreference(subVals);
	}
	public abstract void initializePreference(String[] values) throws Exception;
	
	public abstract AbstractPolicyBuilder getPolicyBuilder();
	
}
